package com.longjianghuasheng.logistics.base

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.longjianghuasheng.logistics.data.model.bean.ApiResponseNoData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel
import me.hgj.jetpackmvvm.ext.executeResponse
import me.hgj.jetpackmvvm.ext.request
import me.hgj.jetpackmvvm.ext.util.loge
import me.hgj.jetpackmvvm.network.AppException
import me.hgj.jetpackmvvm.network.BaseResponse
import me.hgj.jetpackmvvm.network.ExceptionHandle
import me.hgj.jetpackmvvm.state.ResultState

//多布局状态的viewModel
open class BaseMultiStateViewModel : BaseViewModel() {

    var page = 1

    val multiStateLiveData by lazy {
        MutableLiveData<ResultState<String>>()
    }


    //获取数据的网络请求, 在viewModel 层直接获取数据
    fun <T> getData(
        block: suspend () -> BaseResponse<T>,
        success: (T) -> Unit
    ) {
        multiStateLiveData.value = ResultState.onAppLoading("")
        request(block, {
            multiStateLiveData.value = ResultState.onAppSuccess("")
            success(it)
        }, {

            multiStateLiveData.value = ResultState.onAppError(it)
        })

    }


    /**
     * 请求结果过滤，判断请求服务器请求结果是否成功，不成功则会抛出异常
     */
    private suspend fun <T : ApiResponseNoData> executeResponse(
        response: T,
        success: suspend CoroutineScope.(T) -> Unit
    ) {
        coroutineScope {
            when {
                response.isSuccess() -> {
                    success(response)
                }
                else -> {
                    throw AppException(
                        response.getResponseCode(),
                        response.getResponseMsg(),
                        response.getResponseMsg()
                    )
                }
            }
        }
    }

    //获取数据的网络请求，json里没有data时调用  在viewModel 层 直接获取数据
    private fun <T : ApiResponseNoData> BaseViewModel.request2(

        block: suspend () -> T,
        success: (T) -> Unit,
        error: (AppException) -> Unit = {},

        ) {
        viewModelScope.launch {
            runCatching {
                //请求体
                block()
            }.onSuccess {
                runCatching {
                    //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                    executeResponse(it) { t ->
                        success(t)
                    }
                }.onFailure { e ->
                    //打印错误消息
                    e.message?.loge()
                    //失败回调
                    error(ExceptionHandle.handleException(e))
                }
            }.onFailure {
                //打印错误消息
                it.message?.loge()
                //失败回调
                error(ExceptionHandle.handleException(it))
            }
        }
    }


    //获取数据，直接交给view层
    fun <T> getData(
        block: suspend () -> BaseResponse<T>,
        successLiveData: MutableLiveData<T>
    ) {
        getData(block) {
            successLiveData.value = it
        }

    }

    fun <T : ApiResponseNoData> getData2(
        block: suspend () -> T,
        success: (T) -> Unit,
        error: (AppException) -> Unit = {},
    ) {

        multiStateLiveData.value = ResultState.onAppLoading("")
        request2(block, {
            multiStateLiveData.value = ResultState.onAppSuccess("")
            success(it)
        }, {

            multiStateLiveData.value = ResultState.onAppError(it)
        })
    }

    //获取数据，直接交给view层
    fun <T : ApiResponseNoData> getData2(
        block: suspend () -> T,
        successLiveData: MutableLiveData<T>
    ) {
        getData2(block, {
            successLiveData.value = it
        })
    }

}